AVL树--C语言实现


/************************************************************************
 *                        AVL树 demo程序                                
 * Version:1.0    实现insert函数                                        
 * nizqsut 2009.1019 00:04                            
 *                                                                     
 ************************************************************************/
#include
#include

#include "avl_tree.h"
#include "fatal.h"

static avl_tree make_empty(avl_tree t){

    if (t != NULL) {
        if (t->left != NULL) {
            t->left = make_empty(t->left);
        }
        if (t->right != NULL) {
            t->right = make_empty(t->right);
        }
        free(t);
    }

    return NULL;
}

static avl_pos find(avl_element_type element, avl_tree t){

    if (NULL == t) {
        return NULL;
    }

    if (element < t->element) {
        return find(element,t->left);
    }else if (element > t->element) {
        return find(element,t->right);
    }

    return t;
}

static avl_pos find_min(avl_tree t){
    if (NULL == t) {
        return NULL;
    }

    if (NULL == t->left) {
        return t;
    }else{
        return find_min(t->left);
    }
}

static avl_pos find_max(avl_tree t){

    if (NULL != t) {
        while (t->right != NULL) {
            t = t->right;
        }
    }

    return t;
}

static int high(avl_pos p){
    if (p == NULL) {
        return -1;
    }else{
        return p->high;
    }
}

/************************************************************************/
/* This function can be called only if k2 has a left child              */
/* Perform a rotate between a node(k2) and its left child               */
/* Update heights, then return new root                                 */
/************************************************************************/
static avl_pos single_rotate_with_left(avl_tree k2){

    avl_pos k1;

    k1 = k2->left;
    k2->left = k1->right;
    k1->right = k2;
    
    //k2->high = max(k2->left->high,k2->right->high) + 1;
    //k1->high = max(k1->left->high, k2->high) + 1;
    k2->high = max( high(k2->left), high(k2->right) ) + 1;
    k1->high = max( high(k1->left),k2->high ) + 1;
    return k1;
}

static avl_pos single_rotate_with_right(avl_tree k1){

    avl_pos k2;

    k2 = k1->right;

    k1->right = k2->left;
    k2->left = k1;

    //k1->high = max(k1->left->high, k1->right->high) + 1;
    //k2->high = max(k1->high, k2->right->high) + 1;
    k1->high = max( high(k1->left), high(k1->right) ) + 1;
    k2->high = max( k1->high, high(k2->right) ) + 1;

    return k2;
}

static avl_pos double_rotate_with_left(avl_tree k3){

    /* rotate between k1 and k2 */
    k3->left = single_rotate_with_right(k3->left);

    /* rotate between k3 and k2*/
    return single_rotate_with_left(k3);
}

static avl_pos double_rotate_with_right(avl_tree k1){

    /* rotate between k3 and k2 */
    k1->right = single_rotate_with_left(k1->right);

    /* rotate between k1 and k2 */
    return single_rotate_with_right(k1);

}

static avl_tree insert(avl_element_type element, avl_tree t){
   
    if (NULL == t) {
        if ( (t = malloc(sizeof(*t))) == NULL) {
            Error("Out of space!");
            return NULL;
        }
        t->element = element;
        t->right = t->left = NULL;
        t->high = 0;
    }else
    if (element < t->element) {
        t->left = insert(element,t->left);
        //if ( (t->left->high - t->right->high) == 2){
        if ( (high(t->left) - high(t->right)) == 2) {
            if (element < t->left->element) {
                t = single_rotate_with_left(t);
            }else{
                t = double_rotate_with_left(t);
            }
        }
    }else
    if (element > t->element) {
        t->right = insert(element,t->right);
        //if ( (t->right->high - t->left->high) == 2) {
        if ( (high(t->right) - high(t->left)) == 2) {
            if (element > t->right->element) {
                t = single_rotate_with_right(t);
            }else{
                t = double_rotate_with_right(t);
            }
        }
    }else{
        //The element ready is the tree.
        //Do nothing.
    }

    //t->high = max(t->left->high,t->right->high) + 1;
    t->high = max( high(t->left), high(t->right) ) + 1;
    return t;
}

static void visit_t(avl_pos t,int high){
    //if (t) {
    while (high--) {
        printf("\t");
    }
    printf("element = %d, high = %d.\n",t->element,t->high);
    //}else{
    //    Error("NULL Pointer used.");
    //}
}

static void pre_order(avl_tree t,
               void (*visit)(avl_pos t, int high),
               int high)
{

    if (t == NULL) {
        return;
    }
    visit(t,high);

    if (t->left != NULL) {
        pre_order(t->left, visit, high+1);
    }
   
    //visit(t->element,high);

    if (t->right != NULL) {
        pre_order(t->right, visit, high+1);
    }

    return;
}

static int s_tree[] = {3,2,1,4,5,6,7,16,15,14,13,12,11,10,8};

void avl_tree_test(void){

    avl_tree t = NULL;
    int i;

    for (i = 0; i < sizeof(s_tree)/sizeof(s_tree[0]); i++) {
        if ( (t = insert(s_tree[i],t)) == NULL ) {
            Error("Insert error!\n");
            return;
        }
        printf("\t-------------------------------------\n");
        pre_order(t,visit_t,0);
        printf("\t-------------------------------------\n");
    }
    pre_order(t,visit_t,0);
    printf("\n\n");

    //tree_delete(2,t);
    //pre_order(t,visit_t,0);

    return;
}
 
<script>window._bd_share_config={"common":{"bdSnsKey":{},"bdText":"","bdMini":"2","bdMiniList":false,"bdPic":"","bdStyle":"0","bdSize":"16"},"share":{}};with(document)0[(getElementsByTagName('head')[0]||body).appendChild(createElement('script')).src='http://bdimg.share.baidu.com/static/api/js/share.js?v=89860593.js?cdnversion='+~(-new Date()/36e5)];</script>
阅读(1137) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~
评论热议
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值